/*
 * Copyright Aristool AG Switzerland
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */

package org.opprua.dss.application;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.opprua.tidy.util.XReader;

/**
 * TODO: add Java doc
 * 
 * Prepared for first commit: 23.02.2007
 * 
 * @author Lin Li
 */
public class DApplication {

  private Map<String, DComponent> components;
  private Map<String, DSelect> selects;
  private Map<String, DEntry> entries;
  private Map<String, DDataPoint> dataPoints;
  private Map<String, DProvider> providers;
  private List<String> guards = new ArrayList<String>();

  public DApplication() {
  }

  public DApplication(DAppReader[] readers) {
    components = combine(readers, DComponent.class);
    selects = combine(readers, DSelect.class);
    entries = combine(readers, DEntry.class);
    dataPoints = combine(readers, DDataPoint.class);
    providers = combine(readers, DProvider.class);
    
    for (int i = 0; i < readers.length; i++) {
      String h = readers[i].getGuard();
      if (h.length() > 0) {
        guards.add(h);
      }
    }
  }

  public DProvider getProvider(String name) {
    DProvider p = providers.get(name);
    if (p == null) {
      p = new DProvider();
      p.setAttribute("name", name);
      providers.put(name, p);
    }
    return p;
  }

  public void connect() {
    for (Iterator<String> iter = selects.keySet().iterator(); iter.hasNext();) {
      selects.get(iter.next()).registerCalls(this);
    }
    for (Iterator<String> iter = entries.keySet().iterator(); iter.hasNext();) {
      entries.get(iter.next()).registerCalls(this);
    }
    for (Iterator<String> iter = dataPoints.keySet().iterator(); iter.hasNext();) {
      dataPoints.get(iter.next()).registerCalls(this);
    }
  }
  
  public List<String> getGuards() {
    return guards;
  }
  
  public String[] getComponentNames() {
    return components.keySet().toArray(new String[0]);
  }

  public String[] getEntryNames() {
    return entries.keySet().toArray(new String[0]);
  }

  public String[] getProviderNames() {
    return providers.keySet().toArray(new String[0]);
  }

  public String[] getSelectNames() {
    return selects.keySet().toArray(new String[0]);
  }

  public String[] getDataPointNames() {
    return dataPoints.keySet().toArray(new String[0]);
  }

  public DComponent getComponent(String name) {
    return get(components, name, DComponent.class);
  }

  public DEntry getEntry(String name) {
    return get(entries, name, DEntry.class);
  }

  public DSelect getSelect(String name) {
    return get(selects, name, DSelect.class);
  }

  public DDataPoint getDataPoint(String name) {
    return get(dataPoints, name, DDataPoint.class);
  }

  private <T extends XReader> T get(Map<String, T> m, String name, Class<T> t) {
    return m.get(name);
  }

  @SuppressWarnings("unchecked")
  private <T extends XReader> Map<String, T> combine(DAppReader[] apps, Class<T> t) {
    Map<String, T> l = new TreeMap<String, T>();
    for (int i = 0; i < apps.length; i++) {
      T[] d = apps[i].getEls(t);
      if (d != null) {
        for (int j = 0; j < d.length; j++) {
          l.put(d[j].getAttribute("name"), d[j]);
        }
      }
    }
    return l;
  }
}
